#ifndef __REG__H
#define __REG__H
 
#include "stdint.h"

#define __IO volatile

/* General Purpose I/O */
typedef struct
{
    __IO uint32_t CFGLR;
    __IO uint32_t CFGHR;
    __IO uint32_t INDR;
    __IO uint32_t OUTDR;
    __IO uint32_t BSHR;
    __IO uint32_t BCR;
    __IO uint32_t LCKR;
} GPIO_TypeDef;

/* Alternate Function I/O */
typedef struct
{
    __IO uint32_t ECR;
    __IO uint32_t PCFR1;
    __IO uint32_t EXTICR[4];
    uint32_t RESERVED0;
    __IO uint32_t PCFR2;
} AFIO_TypeDef;

/* Power Control */
typedef struct
{
    __IO uint32_t CTLR;
    __IO uint32_t CSR;
} PWR_TypeDef;

/* Reset and Clock Control */
typedef struct
{
  __IO uint32_t CTLR;
  __IO uint32_t CFGR0;
  __IO uint32_t INTR;
  __IO uint32_t APB2PRSTR;
  __IO uint32_t APB1PRSTR;
  __IO uint32_t AHBPCENR;
  __IO uint32_t APB2PCENR;
  __IO uint32_t APB1PCENR;
  __IO uint32_t BDCTLR;
  __IO uint32_t RSTSCKR;
  __IO uint32_t AHBRSTR;
  __IO uint32_t CFGR2;
} RCC_TypeDef;

/* Universal Synchronous Asynchronous Receiver Transmitter */
typedef struct
{
    __IO uint16_t STATR;
    uint16_t RESERVED0;
    __IO uint16_t DATAR;
    uint16_t RESERVED1;
    __IO uint16_t BRR;
    uint16_t RESERVED2;
    __IO uint16_t CTLR1;
    uint16_t RESERVED3;
    __IO uint16_t CTLR2;
    uint16_t RESERVED4;
    __IO uint16_t CTLR3;
    uint16_t RESERVED5;
    __IO uint16_t GPR;
    uint16_t RESERVED6;
    __IO uint16_t CTLR4;
    uint16_t RESERVED7;
} USART_TypeDef;
 


/* Peripheral memory map */
#define FLASH_BASE            ((uint32_t)0x08000000) /* FLASH base address in the alias region */
#define SRAM_BASE             ((uint32_t)0x20000000) /* SRAM base address in the alias region */
#define PERIPH_BASE           ((uint32_t)0x40000000) /* Peripheral base address in the alias region */
 
#define APB1PERIPH_BASE       (PERIPH_BASE)
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000) 
#define UART6_BASE            (APB1PERIPH_BASE + 0x1800)
#define UART7_BASE            (APB1PERIPH_BASE + 0x1C00)
#define UART8_BASE            (APB1PERIPH_BASE + 0x2000)  
#define USART2_BASE           (APB1PERIPH_BASE + 0x4400)
#define USART3_BASE           (APB1PERIPH_BASE + 0x4800)
#define UART4_BASE            (APB1PERIPH_BASE + 0x4C00)
#define UART5_BASE            (APB1PERIPH_BASE + 0x5000) 
#define BKP_BASE              (APB1PERIPH_BASE + 0x6C00)
#define PWR_BASE              (APB1PERIPH_BASE + 0x7000) 
#define AFIO_BASE             (APB2PERIPH_BASE + 0x0000) 
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800) 
#define USART1_BASE           (APB2PERIPH_BASE + 0x3800) 
#define RCC_BASE              (AHBPERIPH_BASE + 0x1000)
#define FLASH_R_BASE          (AHBPERIPH_BASE + 0x2000)
#define CRC_BASE              (AHBPERIPH_BASE + 0x3000)
#define USBHS_BASE            (AHBPERIPH_BASE + 0x3400)
#define EXTEN_BASE            (AHBPERIPH_BASE + 0x3800)
#define OPA_BASE              (AHBPERIPH_BASE + 0x3804)
#define RNG_BASE              (AHBPERIPH_BASE + 0x3C00)

  

#define OB_BASE               ((uint32_t)0x1FFFF800)
#define FEATURE_SIGN          ((uint32_t)0x1FFFF7D0)
 
#define UART6               ((USART_TypeDef *) UART6_BASE)
#define UART7               ((USART_TypeDef *) UART7_BASE)
#define UART8               ((USART_TypeDef *) UART8_BASE)
 
 
#define USART2              ((USART_TypeDef *) USART2_BASE)
#define USART3              ((USART_TypeDef *) USART3_BASE)
#define UART4               ((USART_TypeDef *) UART4_BASE)
#define UART5               ((USART_TypeDef *) UART5_BASE)
 
#define PWR                 ((PWR_TypeDef *) PWR_BASE)
 

#define AFIO                ((AFIO_TypeDef *) AFIO_BASE)
 
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
 
#define USART1              ((USART_TypeDef *) USART1_BASE)
 
 
#define RCC                 ((RCC_TypeDef *) RCC_BASE)
 

 

#if !defined(UNUSED)
#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
#endif                    /* UNUSED */

#define SET_BIT(REG, BIT) ((REG) |= (BIT))

#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))

#define READ_BIT(REG, BIT) ((REG) & (BIT))

#define CLEAR_REG(REG) ((REG) = (0x0))

#define WRITE_REG(REG, VAL) ((REG) = (VAL))

#define READ_REG(REG) ((REG))

/* bit operations */
#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr))
#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr))
#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr))
#define BIT(x) ((uint32_t)((uint32_t)0x01U << (x)))
#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end))))
#define GET_BITS(regval, start, end) (((regval) & BITS((start), (end))) >> (start))

#define SET_REG_BIT(ADDR, BIT) (*(volatile uint32_t *)(ADDR) |= (BIT))
#define CLEAR_REG_BIT(ADDR, BIT) (*(volatile uint32_t *)(ADDR) &= ~(BIT))

#endif